#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
命令模式 (Command Pattern) - Python实现详解

概述引导：
命令模式将请求封装成对象，从而使你可用不同的请求对客户进行参数化；
对请求排队或记录请求日志，以及支持可撤销的操作。

学习要点：
1. 传统命令模式实现
2. 函数式命令模式
3. 宏命令和组合命令
4. 命令队列和异步执行

Java对比要点：
- Java需要定义Command接口和具体命令类
- Python可以直接使用函数作为命令
- Python支持闭包和装饰器简化实现
- Python的动态特性使命令更灵活

关键理解：
命令模式将调用者与接收者解耦，Python的函数式特性使实现更简洁。
"""

from abc import ABC, abstractmethod
from typing import Any, Callable, Dict, List, Optional, Union, Tuple
from dataclasses import dataclass, field
from enum import Enum
from datetime import datetime
import time
import json
import threading
import queue
import asyncio
from functools import wraps, partial
import copy
import uuid


# ============= 传统命令模式 =============

class Command(ABC):
    """
    命令抽象基类
    
    Java对比：
    - Java需要定义Command接口
    - Python使用ABC更灵活
    """
    
    @abstractmethod
    def execute(self) -> Any:
        """执行命令"""
        pass
    
    @abstractmethod
    def undo(self) -> Any:
        """撤销命令"""
        pass
    
    def can_undo(self) -> bool:
        """是否可以撤销"""
        return True
    
    def get_description(self) -> str:
        """获取命令描述"""
        return self.__class__.__name__


class Receiver:
    """
    接收者基类
    
    实际执行操作的对象
    """
    pass


# ============= 文本编辑器示例 =============

class TextEditor(Receiver):
    """
    文本编辑器 - 接收者
    
    实际执行文本操作的类
    """
    
    def __init__(self):
        self._content = ""
        self._cursor_position = 0
        self._selection_start = 0
        self._selection_end = 0
    
    @property
    def content(self) -> str:
        return self._content
    
    @property
    def cursor_position(self) -> int:
        return self._cursor_position
    
    def insert_text(self, text: str, position: int = None) -> int:
        """插入文本"""
        if position is None:
            position = self._cursor_position
        
        self._content = self._content[:position] + text + self._content[position:]
        self._cursor_position = position + len(text)
        return position
    
    def delete_text(self, start: int, end: int) -> str:
        """删除文本"""
        deleted_text = self._content[start:end]
        self._content = self._content[:start] + self._content[end:]
        self._cursor_position = start
        return deleted_text
    
    def replace_text(self, start: int, end: int, new_text: str) -> str:
        """替换文本"""
        old_text = self._content[start:end]
        self._content = self._content[:start] + new_text + self._content[end:]
        self._cursor_position = start + len(new_text)
        return old_text
    
    def set_cursor_position(self, position: int) -> int:
        """设置光标位置"""
        old_position = self._cursor_position
        self._cursor_position = max(0, min(position, len(self._content)))
        return old_position
    
    def select_text(self, start: int, end: int) -> Tuple[int, int]:
        """选择文本"""
        old_selection = (self._selection_start, self._selection_end)
        self._selection_start = max(0, min(start, len(self._content)))
        self._selection_end = max(0, min(end, len(self._content)))
        return old_selection
    
    def get_selected_text(self) -> str:
        """获取选中的文本"""
        return self._content[self._selection_start:self._selection_end]
    
    def get_state(self) -> Dict[str, Any]:
        """获取编辑器状态"""
        return {
            'content': self._content,
            'cursor_position': self._cursor_position,
            'selection_start': self._selection_start,
            'selection_end': self._selection_end
        }
    
    def restore_state(self, state: Dict[str, Any]):
        """恢复编辑器状态"""
        self._content = state['content']
        self._cursor_position = state['cursor_position']
        self._selection_start = state['selection_start']
        self._selection_end = state['selection_end']
    
    def __str__(self):
        return f"TextEditor(content='{self._content}', cursor={self._cursor_position})"


class InsertTextCommand(Command):
    """
    插入文本命令
    """
    
    def __init__(self, editor: TextEditor, text: str, position: int = None):
        self.editor = editor
        self.text = text
        self.position = position
        self.actual_position = None
    
    def execute(self) -> Any:
        """执行插入操作"""
        self.actual_position = self.editor.insert_text(self.text, self.position)
        return f"插入文本: '{self.text}' at position {self.actual_position}"
    
    def undo(self) -> Any:
        """撤销插入操作"""
        if self.actual_position is not None:
            deleted = self.editor.delete_text(
                self.actual_position, 
                self.actual_position + len(self.text)
            )
            return f"撤销插入: 删除了 '{deleted}'"
        return "无法撤销：未执行过"
    
    def get_description(self) -> str:
        return f"插入文本: '{self.text}'"


class DeleteTextCommand(Command):
    """
    删除文本命令
    """
    
    def __init__(self, editor: TextEditor, start: int, end: int):
        self.editor = editor
        self.start = start
        self.end = end
        self.deleted_text = None
    
    def execute(self) -> Any:
        """执行删除操作"""
        self.deleted_text = self.editor.delete_text(self.start, self.end)
        return f"删除文本: '{self.deleted_text}' from {self.start} to {self.end}"
    
    def undo(self) -> Any:
        """撤销删除操作"""
        if self.deleted_text is not None:
            self.editor.insert_text(self.deleted_text, self.start)
            return f"撤销删除: 恢复了 '{self.deleted_text}'"
        return "无法撤销：未执行过"
    
    def get_description(self) -> str:
        return f"删除文本: 位置 {self.start}-{self.end}"


class ReplaceTextCommand(Command):
    """
    替换文本命令
    """
    
    def __init__(self, editor: TextEditor, start: int, end: int, new_text: str):
        self.editor = editor
        self.start = start
        self.end = end
        self.new_text = new_text
        self.old_text = None
    
    def execute(self) -> Any:
        """执行替换操作"""
        self.old_text = self.editor.replace_text(self.start, self.end, self.new_text)
        return f"替换文本: '{self.old_text}' -> '{self.new_text}'"
    
    def undo(self) -> Any:
        """撤销替换操作"""
        if self.old_text is not None:
            self.editor.replace_text(
                self.start, 
                self.start + len(self.new_text), 
                self.old_text
            )
            return f"撤销替换: '{self.new_text}' -> '{self.old_text}'"
        return "无法撤销：未执行过"
    
    def get_description(self) -> str:
        return f"替换文本: '{self.new_text}'"


# ============= 调用者 =============

class CommandInvoker:
    """
    命令调用者
    
    管理命令的执行、撤销和重做
    """
    
    def __init__(self, max_history: int = 100):
        self.command_history: List[Command] = []
        self.current_position = -1
        self.max_history = max_history
    
    def execute_command(self, command: Command) -> Any:
        """执行命令"""
        result = command.execute()
        
        # 如果当前不在历史末尾，清除后续历史
        if self.current_position < len(self.command_history) - 1:
            self.command_history = self.command_history[:self.current_position + 1]
        
        # 添加新命令到历史
        self.command_history.append(command)
        self.current_position += 1
        
        # 限制历史长度
        if len(self.command_history) > self.max_history:
            self.command_history.pop(0)
            self.current_position -= 1
        
        return result
    
    def undo(self) -> Optional[Any]:
        """撤销上一个命令"""
        if self.can_undo():
            command = self.command_history[self.current_position]
            result = command.undo()
            self.current_position -= 1
            return result
        return None
    
    def redo(self) -> Optional[Any]:
        """重做下一个命令"""
        if self.can_redo():
            self.current_position += 1
            command = self.command_history[self.current_position]
            result = command.execute()
            return result
        return None
    
    def can_undo(self) -> bool:
        """是否可以撤销"""
        return (
            self.current_position >= 0 and 
            self.current_position < len(self.command_history) and
            self.command_history[self.current_position].can_undo()
        )
    
    def can_redo(self) -> bool:
        """是否可以重做"""
        return self.current_position < len(self.command_history) - 1
    
    def get_history(self) -> List[str]:
        """获取命令历史"""
        return [cmd.get_description() for cmd in self.command_history]
    
    def clear_history(self):
        """清除历史"""
        self.command_history.clear()
        self.current_position = -1


# ============= 宏命令 =============

class MacroCommand(Command):
    """
    宏命令 - 组合多个命令
    
    Python特色：
    - 支持命令组合
    - 批量执行和撤销
    """
    
    def __init__(self, commands: List[Command], description: str = "宏命令"):
        self.commands = commands.copy()
        self.description = description
        self.executed_commands: List[Command] = []
    
    def execute(self) -> Any:
        """执行所有命令"""
        results = []
        self.executed_commands.clear()
        
        for command in self.commands:
            try:
                result = command.execute()
                results.append(result)
                self.executed_commands.append(command)
            except Exception as e:
                # 如果某个命令失败，撤销已执行的命令
                self.undo()
                raise Exception(f"宏命令执行失败: {e}")
        
        return results
    
    def undo(self) -> Any:
        """撤销所有已执行的命令（逆序）"""
        results = []
        
        # 逆序撤销
        for command in reversed(self.executed_commands):
            try:
                result = command.undo()
                results.append(result)
            except Exception as e:
                print(f"撤销命令失败: {e}")
        
        self.executed_commands.clear()
        return results
    
    def get_description(self) -> str:
        return f"{self.description} ({len(self.commands)}个命令)"
    
    def add_command(self, command: Command):
        """添加命令"""
        self.commands.append(command)
    
    def remove_command(self, command: Command):
        """移除命令"""
        if command in self.commands:
            self.commands.remove(command)


# ============= 函数式命令模式 =============

class FunctionCommand(Command):
    """
    函数式命令 - Python特色实现
    
    将函数封装为命令对象
    """
    
    def __init__(self, execute_func: Callable, undo_func: Callable = None, 
                 description: str = None, *args, **kwargs):
        self.execute_func = execute_func
        self.undo_func = undo_func
        self.description = description or execute_func.__name__
        self.args = args
        self.kwargs = kwargs
        self.execution_result = None
    
    def execute(self) -> Any:
        """执行函数"""
        self.execution_result = self.execute_func(*self.args, **self.kwargs)
        return self.execution_result
    
    def undo(self) -> Any:
        """撤销函数"""
        if self.undo_func:
            return self.undo_func(self.execution_result, *self.args, **self.kwargs)
        else:
            raise NotImplementedError("未提供撤销函数")
    
    def can_undo(self) -> bool:
        return self.undo_func is not None
    
    def get_description(self) -> str:
        return self.description


def command_decorator(undo_func: Callable = None, description: str = None):
    """
    命令装饰器 - Python特色实现
    
    将普通函数转换为命令
    """
    def decorator(func: Callable):
        @wraps(func)
        def wrapper(*args, **kwargs):
            return FunctionCommand(
                execute_func=func,
                undo_func=undo_func,
                description=description or func.__name__,
                *args, **kwargs
            )
        return wrapper
    return decorator


# ============= 命令队列和异步执行 =============

class CommandQueue:
    """
    命令队列 - 支持异步执行
    
    Python特色：
    - 支持优先级
    - 异步执行
    - 批量处理
    """
    
    def __init__(self, max_workers: int = 4):
        self.queue = queue.PriorityQueue()
        self.max_workers = max_workers
        self.workers: List[threading.Thread] = []
        self.running = False
        self.results: Dict[str, Any] = {}
        self.lock = threading.Lock()
    
    def add_command(self, command: Command, priority: int = 0, command_id: str = None) -> str:
        """添加命令到队列"""
        if command_id is None:
            command_id = str(uuid.uuid4())
        
        # 优先级越小越先执行
        self.queue.put((priority, time.time(), command_id, command))
        return command_id
    
    def start(self):
        """启动命令队列处理"""
        if self.running:
            return
        
        self.running = True
        
        for i in range(self.max_workers):
            worker = threading.Thread(target=self._worker, daemon=True)
            worker.start()
            self.workers.append(worker)
    
    def stop(self):
        """停止命令队列处理"""
        self.running = False
        
        # 添加停止信号
        for _ in range(self.max_workers):
            self.queue.put((float('inf'), time.time(), 'STOP', None))
        
        # 等待所有工作线程结束
        for worker in self.workers:
            worker.join()
        
        self.workers.clear()
    
    def _worker(self):
        """工作线程"""
        while self.running:
            try:
                priority, timestamp, command_id, command = self.queue.get(timeout=1)
                
                if command_id == 'STOP':
                    break
                
                # 执行命令
                start_time = time.time()
                try:
                    result = command.execute()
                    execution_time = time.time() - start_time
                    
                    with self.lock:
                        self.results[command_id] = {
                            'status': 'success',
                            'result': result,
                            'execution_time': execution_time,
                            'timestamp': datetime.now()
                        }
                except Exception as e:
                    execution_time = time.time() - start_time
                    
                    with self.lock:
                        self.results[command_id] = {
                            'status': 'error',
                            'error': str(e),
                            'execution_time': execution_time,
                            'timestamp': datetime.now()
                        }
                
                self.queue.task_done()
                
            except queue.Empty:
                continue
            except Exception as e:
                print(f"工作线程错误: {e}")
    
    def get_result(self, command_id: str) -> Optional[Dict[str, Any]]:
        """获取命令执行结果"""
        with self.lock:
            return self.results.get(command_id)
    
    def wait_for_completion(self):
        """等待所有命令完成"""
        self.queue.join()
    
    def get_queue_size(self) -> int:
        """获取队列大小"""
        return self.queue.qsize()


# ============= 异步命令执行器 =============

class AsyncCommandExecutor:
    """
    异步命令执行器
    
    使用asyncio实现异步命令执行
    """
    
    def __init__(self):
        self.running_tasks: Dict[str, asyncio.Task] = {}
    
    async def execute_command_async(self, command: Command, command_id: str = None) -> str:
        """异步执行命令"""
        if command_id is None:
            command_id = str(uuid.uuid4())
        
        async def execute_wrapper():
            # 在线程池中执行同步命令
            loop = asyncio.get_event_loop()
            return await loop.run_in_executor(None, command.execute)
        
        task = asyncio.create_task(execute_wrapper())
        self.running_tasks[command_id] = task
        
        return command_id
    
    async def wait_for_command(self, command_id: str) -> Any:
        """等待命令完成"""
        if command_id in self.running_tasks:
            try:
                result = await self.running_tasks[command_id]
                del self.running_tasks[command_id]
                return result
            except Exception as e:
                del self.running_tasks[command_id]
                raise e
        else:
            raise ValueError(f"未找到命令: {command_id}")
    
    async def execute_commands_parallel(self, commands: List[Command]) -> List[Any]:
        """并行执行多个命令"""
        tasks = []
        
        for command in commands:
            async def execute_wrapper(cmd=command):
                loop = asyncio.get_event_loop()
                return await loop.run_in_executor(None, cmd.execute)
            
            task = asyncio.create_task(execute_wrapper())
            tasks.append(task)
        
        return await asyncio.gather(*tasks)
    
    def cancel_command(self, command_id: str) -> bool:
        """取消命令"""
        if command_id in self.running_tasks:
            task = self.running_tasks[command_id]
            task.cancel()
            del self.running_tasks[command_id]
            return True
        return False
    
    def get_running_commands(self) -> List[str]:
        """获取正在运行的命令"""
        return list(self.running_tasks.keys())


# ============= 实际应用示例 =============

class Calculator(Receiver):
    """
    计算器 - 接收者示例
    """
    
    def __init__(self):
        self.value = 0
        self.history: List[float] = [0]
    
    def add(self, operand: float) -> float:
        """加法"""
        self.value += operand
        self.history.append(self.value)
        return self.value
    
    def subtract(self, operand: float) -> float:
        """减法"""
        self.value -= operand
        self.history.append(self.value)
        return self.value
    
    def multiply(self, operand: float) -> float:
        """乘法"""
        self.value *= operand
        self.history.append(self.value)
        return self.value
    
    def divide(self, operand: float) -> float:
        """除法"""
        if operand == 0:
            raise ValueError("除数不能为零")
        self.value /= operand
        self.history.append(self.value)
        return self.value
    
    def set_value(self, value: float) -> float:
        """设置值"""
        old_value = self.value
        self.value = value
        self.history.append(self.value)
        return old_value
    
    def get_value(self) -> float:
        """获取当前值"""
        return self.value
    
    def get_history(self) -> List[float]:
        """获取历史"""
        return self.history.copy()
    
    def clear(self):
        """清零"""
        self.value = 0
        self.history = [0]


class CalculatorCommand(Command):
    """
    计算器命令基类
    """
    
    def __init__(self, calculator: Calculator, operand: float, operation: str):
        self.calculator = calculator
        self.operand = operand
        self.operation = operation
        self.previous_value = None
    
    def execute(self) -> Any:
        self.previous_value = self.calculator.get_value()
        return self._perform_operation()
    
    def undo(self) -> Any:
        if self.previous_value is not None:
            self.calculator.set_value(self.previous_value)
            return f"撤销{self.operation}: 恢复到 {self.previous_value}"
        return "无法撤销：未执行过"
    
    def _perform_operation(self) -> Any:
        raise NotImplementedError
    
    def get_description(self) -> str:
        return f"{self.operation} {self.operand}"


class AddCommand(CalculatorCommand):
    """加法命令"""
    
    def __init__(self, calculator: Calculator, operand: float):
        super().__init__(calculator, operand, "加")
    
    def _perform_operation(self) -> Any:
        result = self.calculator.add(self.operand)
        return f"加法: {self.previous_value} + {self.operand} = {result}"


class SubtractCommand(CalculatorCommand):
    """减法命令"""
    
    def __init__(self, calculator: Calculator, operand: float):
        super().__init__(calculator, operand, "减")
    
    def _perform_operation(self) -> Any:
        result = self.calculator.subtract(self.operand)
        return f"减法: {self.previous_value} - {self.operand} = {result}"


class MultiplyCommand(CalculatorCommand):
    """乘法命令"""
    
    def __init__(self, calculator: Calculator, operand: float):
        super().__init__(calculator, operand, "乘")
    
    def _perform_operation(self) -> Any:
        result = self.calculator.multiply(self.operand)
        return f"乘法: {self.previous_value} × {self.operand} = {result}"


class DivideCommand(CalculatorCommand):
    """除法命令"""
    
    def __init__(self, calculator: Calculator, operand: float):
        super().__init__(calculator, operand, "除")
    
    def _perform_operation(self) -> Any:
        result = self.calculator.divide(self.operand)
        return f"除法: {self.previous_value} ÷ {self.operand} = {result}"


# ============= 演示函数 =============

def demonstrate_traditional_command():
    """
    演示传统命令模式
    
    概述引导：
    展示传统命令模式的实现，包括命令接口、具体命令类、
    接收者和调用者的协作。
    
    学习要点：
    1. 命令接口的定义
    2. 具体命令的实现
    3. 调用者的管理
    4. 撤销和重做机制
    
    关键理解：
    命令模式将请求封装成对象，实现调用者与接收者的解耦。
    """
    print("=== 传统命令模式演示 ===")
    print("\n学习目标：")
    print("- 理解命令模式的结构")
    print("- 掌握命令的封装和执行")
    print("- 学习撤销和重做机制")
    print("\n重点概念：")
    print("- 请求的封装")
    print("- 调用者与接收者解耦")
    print("- 可撤销的操作")
    print("=" * 50)
    
    # 创建文本编辑器和命令调用者
    editor = TextEditor()
    invoker = CommandInvoker()
    
    print(f"\n初始编辑器状态: {editor}")
    
    # 执行一系列编辑命令
    commands = [
        InsertTextCommand(editor, "Hello "),
        InsertTextCommand(editor, "World!"),
        InsertTextCommand(editor, " Python is awesome."),
        ReplaceTextCommand(editor, 6, 12, "Python"),
        DeleteTextCommand(editor, 13, 25)
    ]
    
    print("\n=== 执行命令序列 ===")
    for i, command in enumerate(commands):
        result = invoker.execute_command(command)
        print(f"{i+1}. {result}")
        print(f"   编辑器状态: {editor}")
    
    print(f"\n命令历史: {invoker.get_history()}")
    
    # 测试撤销操作
    print("\n=== 撤销操作测试 ===")
    for i in range(3):
        if invoker.can_undo():
            result = invoker.undo()
            print(f"撤销 {i+1}: {result}")
            print(f"   编辑器状态: {editor}")
        else:
            print(f"撤销 {i+1}: 无法撤销")
    
    # 测试重做操作
    print("\n=== 重做操作测试 ===")
    for i in range(2):
        if invoker.can_redo():
            result = invoker.redo()
            print(f"重做 {i+1}: {result}")
            print(f"   编辑器状态: {editor}")
        else:
            print(f"重做 {i+1}: 无法重做")


def demonstrate_macro_command():
    """
    演示宏命令
    """
    print("\n=== 宏命令演示 ===")
    
    editor = TextEditor()
    invoker = CommandInvoker()
    
    # 创建宏命令：格式化文本
    format_commands = [
        InsertTextCommand(editor, "def hello_world():\n"),
        InsertTextCommand(editor, "    print('Hello, World!')\n"),
        InsertTextCommand(editor, "    return True\n")
    ]
    
    format_macro = MacroCommand(format_commands, "格式化Python函数")
    
    print(f"\n初始编辑器: {editor}")
    
    # 执行宏命令
    print("\n执行宏命令:")
    result = invoker.execute_command(format_macro)
    print(f"宏命令结果: {len(result)}个命令执行完成")
    print(f"编辑器内容:\n{editor.content}")
    
    # 撤销宏命令
    print("\n撤销宏命令:")
    undo_result = invoker.undo()
    print(f"撤销结果: {len(undo_result)}个命令被撤销")
    print(f"编辑器状态: {editor}")


def demonstrate_functional_command():
    """
    演示函数式命令
    """
    print("\n=== 函数式命令演示 ===")
    
    # 创建计算器
    calc = Calculator()
    invoker = CommandInvoker()
    
    # 定义操作函数
    def add_operation(calculator, value):
        return calculator.add(value)
    
    def subtract_operation(calculator, value):
        return calculator.subtract(value)
    
    def undo_add(result, calculator, value):
        return calculator.subtract(value)
    
    def undo_subtract(result, calculator, value):
        return calculator.add(value)
    
    # 创建函数式命令
    commands = [
        FunctionCommand(add_operation, undo_add, "加法", calc, 10),
        FunctionCommand(subtract_operation, undo_subtract, "减法", calc, 3),
        FunctionCommand(add_operation, undo_add, "加法", calc, 7),
        FunctionCommand(subtract_operation, undo_subtract, "减法", calc, 2)
    ]
    
    print(f"\n初始计算器值: {calc.get_value()}")
    
    # 执行函数式命令
    print("\n执行函数式命令:")
    for i, command in enumerate(commands):
        result = invoker.execute_command(command)
        print(f"{i+1}. {command.get_description()}: {result}, 当前值: {calc.get_value()}")
    
    # 测试撤销
    print("\n撤销操作:")
    for i in range(2):
        if invoker.can_undo():
            result = invoker.undo()
            print(f"撤销 {i+1}: {result}, 当前值: {calc.get_value()}")


def demonstrate_command_queue():
    """
    演示命令队列
    """
    print("\n=== 命令队列演示 ===")
    
    # 创建命令队列
    command_queue = CommandQueue(max_workers=2)
    command_queue.start()
    
    # 创建一些耗时的命令
    class SlowCommand(Command):
        def __init__(self, name: str, duration: float):
            self.name = name
            self.duration = duration
        
        def execute(self) -> Any:
            time.sleep(self.duration)
            return f"{self.name} 执行完成 (耗时 {self.duration}秒)"
        
        def undo(self) -> Any:
            return f"{self.name} 撤销"
        
        def get_description(self) -> str:
            return self.name
    
    # 添加命令到队列
    command_ids = []
    commands_info = [
        ("高优先级任务", 0.5, 0),  # 高优先级
        ("普通任务1", 1.0, 5),
        ("普通任务2", 0.8, 5),
        ("低优先级任务", 1.2, 10),  # 低优先级
        ("紧急任务", 0.3, 1)   # 紧急任务
    ]
    
    print("\n添加命令到队列:")
    for name, duration, priority in commands_info:
        command = SlowCommand(name, duration)
        command_id = command_queue.add_command(command, priority)
        command_ids.append(command_id)
        print(f"添加: {name} (优先级: {priority}, ID: {command_id[:8]}...)")
    
    print(f"\n队列大小: {command_queue.get_queue_size()}")
    
    # 等待所有命令完成
    print("\n等待命令执行完成...")
    command_queue.wait_for_completion()
    
    # 查看结果
    print("\n执行结果:")
    for command_id in command_ids:
        result = command_queue.get_result(command_id)
        if result:
            print(f"ID {command_id[:8]}: {result['status']} - {result.get('result', result.get('error'))}")
            print(f"  执行时间: {result['execution_time']:.2f}秒")
    
    # 停止队列
    command_queue.stop()


async def demonstrate_async_command():
    """
    演示异步命令执行
    """
    print("\n=== 异步命令执行演示 ===")
    
    executor = AsyncCommandExecutor()
    
    # 创建异步命令
    class AsyncCommand(Command):
        def __init__(self, name: str, duration: float):
            self.name = name
            self.duration = duration
        
        def execute(self) -> Any:
            time.sleep(self.duration)  # 模拟耗时操作
            return f"{self.name} 异步执行完成"
        
        def undo(self) -> Any:
            return f"{self.name} 异步撤销"
        
        def get_description(self) -> str:
            return self.name
    
    # 创建多个异步命令
    commands = [
        AsyncCommand("异步任务1", 1.0),
        AsyncCommand("异步任务2", 0.5),
        AsyncCommand("异步任务3", 0.8)
    ]
    
    print("\n启动异步命令执行:")
    start_time = time.time()
    
    # 并行执行所有命令
    results = await executor.execute_commands_parallel(commands)
    
    end_time = time.time()
    
    print(f"\n并行执行结果 (总耗时: {end_time - start_time:.2f}秒):")
    for i, result in enumerate(results):
        print(f"{i+1}. {result}")
    
    # 测试单个异步命令
    print("\n单个异步命令测试:")
    single_command = AsyncCommand("单独任务", 0.3)
    command_id = await executor.execute_command_async(single_command)
    print(f"命令ID: {command_id[:8]}...")
    
    result = await executor.wait_for_command(command_id)
    print(f"执行结果: {result}")


def demonstrate_calculator_commands():
    """
    演示计算器命令应用
    """
    print("\n=== 计算器命令应用演示 ===")
    
    calc = Calculator()
    invoker = CommandInvoker()
    
    # 创建计算命令序列
    commands = [
        AddCommand(calc, 10),      # 0 + 10 = 10
        MultiplyCommand(calc, 3),  # 10 * 3 = 30
        SubtractCommand(calc, 5),  # 30 - 5 = 25
        DivideCommand(calc, 5),    # 25 / 5 = 5
        AddCommand(calc, 15),      # 5 + 15 = 20
    ]
    
    print(f"\n初始值: {calc.get_value()}")
    
    # 执行计算命令
    print("\n执行计算命令:")
    for i, command in enumerate(commands):
        result = invoker.execute_command(command)
        print(f"{i+1}. {result}")
    
    print(f"\n最终值: {calc.get_value()}")
    print(f"计算历史: {calc.get_history()}")
    
    # 撤销一些操作
    print("\n撤销最后两个操作:")
    for i in range(2):
        if invoker.can_undo():
            result = invoker.undo()
            print(f"撤销 {i+1}: {result}")
            print(f"   当前值: {calc.get_value()}")
    
    # 重做操作
    print("\n重做一个操作:")
    if invoker.can_redo():
        result = invoker.redo()
        print(f"重做: {result}")
        print(f"   当前值: {calc.get_value()}")


def demonstrate_java_comparison():
    """
    Java对比演示
    
    Java等价代码：
    ```java
    // Java版本的命令模式
    public interface Command {
        void execute();
        void undo();
        boolean canUndo();
        String getDescription();
    }
    
    public class InsertTextCommand implements Command {
        private TextEditor editor;
        private String text;
        private int position;
        
        public InsertTextCommand(TextEditor editor, String text, int position) {
            this.editor = editor;
            this.text = text;
            this.position = position;
        }
        
        @Override
        public void execute() {
            editor.insertText(text, position);
        }
        
        @Override
        public void undo() {
            editor.deleteText(position, position + text.length());
        }
        
        @Override
        public boolean canUndo() {
            return true;
        }
        
        @Override
        public String getDescription() {
            return "Insert: " + text;
        }
    }
    
    public class CommandInvoker {
        private Stack<Command> history = new Stack<>();
        private Stack<Command> redoStack = new Stack<>();
        
        public void executeCommand(Command command) {
            command.execute();
            history.push(command);
            redoStack.clear();
        }
        
        public void undo() {
            if (!history.isEmpty()) {
                Command command = history.pop();
                command.undo();
                redoStack.push(command);
            }
        }
        
        public void redo() {
            if (!redoStack.isEmpty()) {
                Command command = redoStack.pop();
                command.execute();
                history.push(command);
            }
        }
    }
    
    // 使用
    TextEditor editor = new TextEditor();
    CommandInvoker invoker = new CommandInvoker();
    Command command = new InsertTextCommand(editor, "Hello", 0);
    invoker.executeCommand(command);
    invoker.undo();
    ```
    
    Python优势：
    1. 函数可以直接作为命令
    2. 装饰器简化命令创建
    3. 异步命令执行支持
    4. 更灵活的命令组合
    """
    print("\n=== Java对比说明 ===")
    print("\nPython优势：")
    print("1. 函数可以直接作为命令")
    print("2. 装饰器简化命令创建")
    print("3. 异步命令执行支持")
    print("4. 更灵活的命令组合")
    print("5. 动态命令队列")
    
    print("\nJava特点：")
    print("1. 强类型的命令接口")
    print("2. 编译时类型检查")
    print("3. 更明确的契约")
    print("4. 更好的IDE支持")
    
    # 演示Python的函数式优势
    print("\n=== Python函数式命令演示 ===")
    
    # 使用lambda作为简单命令
    simple_commands = {
        '打印消息': lambda: print("Hello from lambda command!"),
        '计算平方': lambda x: x ** 2,
        '字符串反转': lambda s: s[::-1]
    }
    
    for name, cmd in simple_commands.items():
        try:
            if name == '打印消息':
                result = cmd()
            elif name == '计算平方':
                result = cmd(5)
            else:
                result = cmd("Python")
            print(f"{name}: {result}")
        except Exception as e:
            print(f"{name}: 错误 - {e}")


def performance_comparison():
    """
    性能对比测试
    """
    print("\n=== 性能对比 ===")
    
    # 创建大量命令的性能测试
    calc = Calculator()
    invoker = CommandInvoker(max_history=1000)
    
    # 测试传统命令模式性能
    print("\n传统命令模式性能测试:")
    start_time = time.time()
    
    for i in range(1000):
        command = AddCommand(calc, 1)
        invoker.execute_command(command)
    
    traditional_time = time.time() - start_time
    print(f"执行1000个传统命令: {traditional_time:.4f}秒")
    print(f"最终计算器值: {calc.get_value()}")
    
    # 测试函数式命令性能
    calc.clear()
    invoker.clear_history()
    
    print("\n函数式命令性能测试:")
    start_time = time.time()
    
    def add_one(calculator):
        return calculator.add(1)
    
    def undo_add_one(result, calculator):
        return calculator.subtract(1)
    
    for i in range(1000):
        command = FunctionCommand(add_one, undo_add_one, "加1", calc)
        invoker.execute_command(command)
    
    functional_time = time.time() - start_time
    print(f"执行1000个函数式命令: {functional_time:.4f}秒")
    print(f"最终计算器值: {calc.get_value()}")
    
    # 测试撤销性能
    print("\n撤销性能测试:")
    start_time = time.time()
    
    for i in range(500):
        if invoker.can_undo():
            invoker.undo()
    
    undo_time = time.time() - start_time
    print(f"撤销500个命令: {undo_time:.4f}秒")
    print(f"最终计算器值: {calc.get_value()}")
    
    print(f"\n性能对比:")
    print(f"传统命令: {traditional_time:.4f}秒")
    print(f"函数式命令: {functional_time:.4f}秒")
    print(f"撤销操作: {undo_time:.4f}秒")
    print(f"函数式命令相对性能: {functional_time / traditional_time:.2f}x")


async def main():
    """主函数"""
    demonstrate_traditional_command()
    demonstrate_macro_command()
    demonstrate_functional_command()
    demonstrate_command_queue()
    await demonstrate_async_command()
    demonstrate_calculator_commands()
    demonstrate_java_comparison()
    performance_comparison()


if __name__ == "__main__":
    asyncio.run(main())